package com.hylanda.processor;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.nifi.annotation.behavior.ReadsAttribute;
import org.apache.nifi.annotation.behavior.ReadsAttributes;
import org.apache.nifi.annotation.behavior.WritesAttribute;
import org.apache.nifi.annotation.behavior.WritesAttributes;
import org.apache.nifi.annotation.documentation.CapabilityDescription;
import org.apache.nifi.annotation.documentation.SeeAlso;
import org.apache.nifi.annotation.documentation.Tags;
import org.apache.nifi.components.PropertyDescriptor;
import org.apache.nifi.logging.ComponentLog;
import org.apache.nifi.processor.ProcessContext;
import org.apache.nifi.processor.ProcessorInitializationContext;
import org.apache.nifi.processor.util.StandardValidators;
import org.apache.nifi.util.StringUtils;

/**
 * 
 * @author linda
 * @version created at：2017年12月22日
 * 
 */
@Tags({ "valley", "chord" })
@CapabilityDescription("接收上层传递的数据，写入Azure上的platform数据库的" + ChordProcessor.DATA_TABLE + "；在配置界面中配置展现参数，写入"
		+ ChordProcessor.CFG_TABLE + "表；" + "通过平台提供的接口获取processor_id，并写入两张相关表。")
@SeeAlso({})
@ReadsAttributes({ @ReadsAttribute(attribute = "", description = "") })
@WritesAttributes({ @WritesAttribute(attribute = "", description = "") })
public class ChordProcessor extends ReportProcessor {
	static final String CFG_TABLE = "M_Chord_cfg";
	static final String DATA_TABLE = "M_Chord";
	static final int COLUMN_SIZE = 3;
	static final String LEFT = "[left]";
	static final String RIGHT = "[right]";

	// 模型显示配置
	public static final PropertyDescriptor TITLE_PROPERTY = new PropertyDescriptor.Builder().name("model-title")
			.displayName("◆            标题").description("贡献分析模型中需要显示的标题").required(false)
			.addValidator(StandardValidators.NON_EMPTY_VALIDATOR).defaultValue("贡献分析").build();

	public static final PropertyDescriptor LEFT_PROPERTY = new PropertyDescriptor.Builder().name("left-name")
			.displayName("◆            左边显示名称").description("贡献分析模型中左边显示名称").required(false)
			.addValidator(StandardValidators.NON_EMPTY_VALIDATOR).build();

	public static final PropertyDescriptor RIGHT_PROPERTY = new PropertyDescriptor.Builder().name("right-name")
			.displayName("◆           右边显示名称").description("贡献分析模型中右边显示名称").required(false)
			.addValidator(StandardValidators.NON_EMPTY_VALIDATOR).build();

	// 模型数据配置
	public static final PropertyDescriptor DIMENSION1_PROPERTY = new PropertyDescriptor.Builder()
			.name(COLUMN_PREFIX + "0").displayName("◆            维度一").description("维度一字段名称").required(false)
			.addValidator(StandardValidators.NON_EMPTY_VALIDATOR).build();

	public static final PropertyDescriptor DIMENSION2_PROPERTY = new PropertyDescriptor.Builder()
			.name(COLUMN_PREFIX + "1").displayName("◆            维度二").description("维度二字段名称").required(false)
			.addValidator(StandardValidators.NON_EMPTY_VALIDATOR).build();

	public static final PropertyDescriptor VALUES_PROPERTY = new PropertyDescriptor.Builder()
			.name(COLUMN_PREFIX + "2").displayName("◆            贡献值").description("贡献值字段名称，类型为bigint")
			.required(false).addValidator(StandardValidators.NON_EMPTY_VALIDATOR).build();

	public ChordProcessor() {
		super(DATA_TABLE, CFG_TABLE, COLUMN_SIZE);
	}

	@Override
	protected void init(final ProcessorInitializationContext context) {
		super.init(context);
		final List<PropertyDescriptor> descriptors = new ArrayList<PropertyDescriptor>();
		descriptors.add(CFG_DESCRIPTOR);
		descriptors.add(TITLE_PROPERTY);
		descriptors.add(LEFT_PROPERTY);
		descriptors.add(RIGHT_PROPERTY);

		descriptors.add(DATA_DESCRIPTOR);
		descriptors.add(DIMENSION1_PROPERTY);
		descriptors.add(DIMENSION2_PROPERTY);
		descriptors.add(VALUES_PROPERTY);

		descriptors.add(CONTROL_DESCRIPTOR);
		descriptors.add(CONTROL_VALUES);

		this.descriptors = Collections.unmodifiableList(descriptors);
	}

	/**
	 * 保存显示配置
	 * 
	 * @param context
	 * @throws Exception
	 */
	protected void saveCfg(ProcessContext context, String[] columns) throws Exception {
		final ComponentLog logger = getLogger();
		// 添加配置信息
		final String title = context.getProperty(TITLE_PROPERTY).getValue();
		final String left = context.getProperty(LEFT_PROPERTY).getValue();
		final String right = context.getProperty(RIGHT_PROPERTY).getValue();
		final StringBuilder sqlAccumulator1 = new StringBuilder();
		sqlAccumulator1.append("if not exists (select 1 from ").append(CFG_TABLE)
				.append(" where processor_id = '").append(getIdentifier()).append("' )");
		sqlAccumulator1.append("insert into ").append(CFG_TABLE).append("(processor_id, title,").append(LEFT)
				.append(",").append(RIGHT).append(") values('").append(getIdentifier()).append("', '")
				.append(title).append("', '").append(left).append("', '").append(right).append("') ");
		sqlAccumulator1.append("else update ").append(CFG_TABLE).append(" set title = '").append(title)
				.append("',").append(LEFT).append("='").append(left).append("',").append(RIGHT).append("='")
				.append(right).append("' where processor_id = '").append(getIdentifier()).append("'");
		logger.debug(sqlAccumulator1.toString());
		final StringBuilder sqlAccumulator = new StringBuilder();
		// 添加数据信息
		if (!StringUtils.isEmpty(columns[0]) && !StringUtils.isEmpty(columns[1])) {
			try {
				final Long valuesL = Long.parseLong(columns[2]);
				sqlAccumulator.append("insert into ").append(DATA_TABLE).append("(processor_id,").append(LEFT)
						.append(",").append(RIGHT).append(",").append(VALUES).append("");
				sqlAccumulator.append(") values('").append(getIdentifier()).append("','").append(columns[0])
						.append("','").append(columns[1]).append("',").append(valuesL);

				sqlAccumulator.append(")");
			} catch (Exception e) {
				sqlAccumulator.setLength(0);
				logger.error("saveDataToDB {} error {}", new Object[] { DATA_TABLE, e.getMessage() });
			}
			logger.debug(sqlAccumulator.toString());
		}

		this.saveToDB(sqlAccumulator1, sqlAccumulator);
	}
}
